package demoMod.stsconsole.rooms;

import demoMod.stsconsole.cards.AbstractCard;
import demoMod.stsconsole.characters.AbstractPlayer;
import demoMod.stsconsole.chests.AbstractChest;
import demoMod.stsconsole.core.CombatManager;
import demoMod.stsconsole.dungeons.AbstractDungeon;
import demoMod.stsconsole.potions.AbstractPotion;
import demoMod.stsconsole.powers.AbstractPower;
import demoMod.stsconsole.relics.AbstractRelic;
import demoMod.stsconsole.rewards.AbstractReward;
import demoMod.stsconsole.helpers.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class AbstractRoom {
    public MonsterGroup monsters = new MonsterGroup();
    public RoomPhase phase;
    public AbstractChest chest;
    public CombatManager combatManager;
    protected List<AbstractRelic.RelicRarity> relicRarityPool = new ArrayList<>();
    public List<AbstractReward> rewards = new ArrayList<>();
    public int commonCardChance;
    public int uncommonCardChance;
    public int commonPotionChance;
    public int uncommonPotionChance;
    public boolean shouldDropReward = true;
    public int goldAmount = 0;

    public AbstractRoom() {
        initRelicRarityPool();
        initCardRarityChance();
        initPotionRarityChance();
    }

    public void onPlayerEntry() {
        while (!PromptHelper.getCurrentHierarchy().equals("")) {
            PromptHelper.backwardPrompt();
        }
        PromptHelper.appendPrompt("Dungeon");
    }

    public abstract String getRoomSymbol();

    public void enterCombat(String encounterId) {
        MonsterHelper.getEncounter(encounterId, this);
        PromptHelper.appendPrompt("Combat");
        System.out.println(LocalizedStrings.getUIStrings("AbstractRoom").get(0) + MonsterHelper.getEncounterNameById(encounterId));
        AbstractPlayer p = AbstractDungeon.player;
        for (AbstractPower power : p.getPowers()) {
            if (!power.isDone) power.onRemove();
        }
        p.getPowers().clear();
        CardHelper.clearCardGroup(p.drawPile);
        CardHelper.clearCardGroup(p.hand);
        CardHelper.clearCardGroup(p.discardPile);
        CardHelper.clearCardGroup(p.exhaustPile);
        List<AbstractCard> innateList = new ArrayList<>();
        for (AbstractCard card : p.masterDeck) {
            if (card.isInnate) {
                innateList.add(card.makeStatEquivalentCopy());
            } else {
                p.drawPile.add(card.makeStatEquivalentCopy());
            }
        }
        Collections.shuffle(p.drawPile, AbstractDungeon.cardRng);
        Collections.shuffle(innateList, AbstractDungeon.cardRng);
        p.drawPile.addAll(0, innateList);
        combatManager = new CombatManager(encounterId);
        combatManager.startCombat();
    }

    public void dropReward() {

    }

    protected void initRelicRarityPool() {
        for (int i=0;i<51;i++) {
            relicRarityPool.add(AbstractRelic.RelicRarity.COMMON);
        }

        for (int i=0;i<17;i++) {
            relicRarityPool.add(AbstractRelic.RelicRarity.RARE);
        }

        while (relicRarityPool.size() < 100) {
            relicRarityPool.add(AbstractRelic.RelicRarity.UNCOMMON);
        }
    }

    protected void initCardRarityChance() {
        this.commonCardChance = 53;
        this.uncommonCardChance = 40;
    }

    protected void initPotionRarityChance() {
        this.commonPotionChance = 50;
        this.uncommonPotionChance = 30;
    }

    public AbstractRelic.RelicRarity getRandomRelicRarity(RandomSequence rng) {
        return relicRarityPool.get(rng.nextInt(relicRarityPool.size()));
    }

    public AbstractCard.CardRarity getRandomCardRarity(RandomSequence rng) {
        int roll = rng.nextInt(100) + AbstractDungeon.cardRarityBlizzardCount;
        int chance = this.commonCardChance;
        if (roll < chance) {
            AbstractDungeon.cardRarityBlizzardCount += 5;
            return AbstractCard.CardRarity.COMMON;
        }
        chance += this.uncommonCardChance;
        if (roll < chance) {
            return AbstractCard.CardRarity.UNCOMMON;
        } else {
            AbstractDungeon.cardRarityBlizzardCount = 0;
            return AbstractCard.CardRarity.RARE;
        }
    }

    public AbstractPotion.PotionRarity getRandomPotionRarity(RandomSequence rng) {
        int roll = rng.nextInt(100);
        int chance = this.commonPotionChance;
        if (roll < chance) {
            return AbstractPotion.PotionRarity.COMMON;
        }
        chance += this.uncommonPotionChance;
        if (roll < chance) {
            return AbstractPotion.PotionRarity.UNCOMMON;
        } else {
            return AbstractPotion.PotionRarity.RARE;
        }
    }

    public enum RoomPhase {
        UNCOMPLETED, COMBAT, COMPLETED
    }
}
